package com.gosling.cloudspace.tools;


import cn.hutool.core.io.FileUtil;
import com.alibaba.excel.ExcelWriter;
import com.ctc.wstx.sw.XmlWriter;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.dom4j.io.XMLWriter;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.io.*;
import java.nio.channels.FileChannel;

/**
 * 通用关流方法
 *
 * @Software: IntelliJ IDEA
 * @Addresses: www.gosling.com
 * @Email 1793327033@qq.com
 * @Classname IOTool
 * @Author: lihonglin
 * @Date: 2021/10/21 9:59
 */
public class IOTool {

    /***
     * Closes this stream and releases any system resources associated
     * with it. If the stream is already closed then invoking this
     * method has no effect.
     * 原继承方法会自动排除异常
     *
     * @param writer
     */
    public static void closeQuietly(ExcelWriter writer) {
        try {
            if (writer != null) {
                writer.finish();
            }
        } catch (Exception ioe) {
            ioe.printStackTrace();
        }
    }

    public static void closeQuietly(BufferedReader writer) {
        try {
            if (writer != null) {
                writer.close();
            }
        } catch (Exception ioe) {
            ioe.printStackTrace();
        }
    }

    public static void closeQuietly(OutputStream outputStream) {
        try {
            if (outputStream != null) {
                outputStream.close();
            }
        } catch (Exception ioe) {
            ioe.printStackTrace();
        }
    }

    public static void closeQuietly(ServletOutputStream closeable) {
        try {
            if (closeable != null) {
                closeable.flush();
                closeable.close();
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    /***
     * Closes this stream and releases any system resources associated
     * with it. If the stream is already closed then invoking this
     * method has no effect.
     * 原继承方法会自动排除异常
     *
     * @param xsw
     */
    public static void closeQuietly(XMLStreamWriter xsw) {
        try {
            if (xsw != null) {
                xsw.flush();
                xsw.close();
            }
        } catch (XMLStreamException e) {
            e.printStackTrace();
        }
    }

    /***
     * FileOutputStream：输出流关闭并刷新
     *
     * @param out
     */
    public static void closeQuietly(FileOutputStream out) {
        closeAndTry(out);
    }

    private static void closeAndTry(FileOutputStream out) {
        try {
            if (out != null) {
                out.flush();
                out.close();
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    /***
     * XmlWriter：XML关闭写出
     *
     * @param writer
     */
    public static void closeQuietly(XmlWriter writer) {
        try {
            if (writer != null) {
                writer.flush();
                writer.close(true);
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    /***
     * XmlWriter：XML关闭写出
     *
     * @param writer
     */
    public static void closeQuietly(XMLEventReader writer) {
        try {
            if (writer != null) {
                writer.close();
            }
        } catch (Exception ioe) {
            ioe.printStackTrace();
        }
    }

    /***
     * XmlWriter：XML关闭写出
     *
     * @param writer
     */
    public static void closeQuietly(XMLWriter writer) {
        try {
            if (writer != null) {
                writer.flush();
                writer.close();
            }
        } catch (Exception ioe) {
            ioe.printStackTrace();
        }
    }

    public static void closeQuietly(SXSSFWorkbook writer) {
        try {
            if (writer != null) {
                writer.close();
                writer.dispose();
            }
        } catch (Exception ioe) {
            ioe.printStackTrace();
        }
    }

    /***
     * FileInputStream：输入流关闭
     *
     * @param in
     */
    public static void closeQuietly(FileInputStream in) {
        try {
            if (in != null) {
                in.close();
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    /***
     * FileChannel：信道
     *
     * @param fileChannel
     */
    public static void closeQuietly(FileChannel fileChannel) {
        try {
            if (fileChannel != null) {
                fileChannel.close();
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    /***
     * IO写出
     *
     * @param writer
     */
    public static void closeQuietly(Writer writer) {
        try {
            if (writer != null) {
                writer.close();
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    /**
     * 向客户端输出文件并清除本地文件
     *
     * @param response
     * @param filePath
     */
    public static void outStreamWrite(HttpServletResponse response, String filePath, String contentType, String contentDisposition) {
        //response为HttpServletResponse对象
        response.setContentType(contentType);
        //test.xls是弹出下载对话框的文件名，不能为中文，中文请自行编码
        response.setHeader("Content-Disposition", contentDisposition);
        ;
        OutputStream outStream = null;
        try {
            outStream = new BufferedOutputStream(response.getOutputStream());
            outStream.write(file2buf(new File(filePath)));
            outStream.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            closeQuietly(outStream);
            if (FileUtil.exist(filePath)) {
                FileUtil.del(filePath);
            }
        }
    }

    /**
     * 文件转字节数组
     *
     * @param fobj
     * @return
     */
    public static byte[] file2buf(File fobj) {
        byte[] buffer = null;
        try {
            if (!fobj.exists()) {
                return null;
            }
            FileInputStream fis = new FileInputStream(fobj);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int len = -1;
            while ((len = fis.read(b)) != -1) {
                bos.write(b, 0, len);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }

}
